#include "ventanamapas.h"

VentanaMapas :: VentanaMapas() : area(vContinentes, cargarImagen){
	
	cargarImagen = false;
	ruta.assign("");
	
	//inicializo las posiciones
	iniOk = false;
	iniEliOk = false;
	
	//Armo el menu de arriba
	vBox.pack_start(menu, false, true);
	bNuevo.set_label("Nuevo");
	bNuevo.signal_clicked().connect( sigc::mem_fun(*this,
			            &VentanaMapas::on_nuevo_clicked));
	bCargar.set_label("Cargar");
	bCargar.signal_clicked().connect( sigc::mem_fun(*this,
			            &VentanaMapas::on_cargar_clicked));
	bGuardar.set_label("Guardar");
	bGuardar.signal_clicked().connect( sigc::mem_fun(*this,
			            &VentanaMapas::on_guardar_clicked));
	menu.pack_start(bNuevo, true, true, 0);
	menu.pack_start(bCargar,true, true,0);
	menu.pack_start(bGuardar,true,true,0);
	
	//imagen
	eventos.add(area);
	eventos.set_events(Gdk::BUTTON_PRESS_MASK);
	eventos.signal_button_press_event().connect(sigc::mem_fun(*this, &VentanaMapas::on_imagen_clicked));
	vBox.pack_start(eventos, true, true, 0);
	
	//separador
	vBox.pack_start(separador, false, false, 5);
	
	//consola
	detalles.set_editable(false);
	barra.add(detalles);
	vBox.pack_start(barra,false,true,0);
	
	//separador
	vBox.pack_start(separador2, false, false, 5);
	
	//menu de abajo
	bAgregarContinente.set_label("Agregar Continente");
	bAgregarContinente.signal_clicked().connect( sigc::mem_fun(*this,
	            &VentanaMapas::on_continente_clicked));
	bEliminarContinente.set_label("Eliminar Continente");
	bEliminarContinente.signal_clicked().connect( sigc::mem_fun(*this,
		            &VentanaMapas::on_eliminar_continente_clicked));
	this->vBoxContinente.pack_start(bAgregarContinente);
	this->vBoxContinente.pack_start(bEliminarContinente);
		
	bAgregarConeccion.set_label("Agregar Conección");
	bAgregarConeccion.signal_clicked().connect( sigc::mem_fun(*this,
	            &VentanaMapas::on_coneccion_clicked));
	bEliminarConeccion.set_label("Eliminar Conección");
	bEliminarConeccion.signal_clicked().connect( sigc::mem_fun(*this,
		            &VentanaMapas::on_eliminar_coneccion_clicked));
	this->vBoxConeccion.pack_start(bAgregarConeccion);
	this->vBoxConeccion.pack_start(bEliminarConeccion);
		
	bAgregarPais.set_label("Agregar País");
	bAgregarPais.signal_clicked().connect( sigc::mem_fun(*this,
		            &VentanaMapas::on_pais_clicked));
	bEliminarPais.set_label("Eliminar País");
	bEliminarPais.signal_clicked().connect( sigc::mem_fun(*this,
			            &VentanaMapas::on_eliminar_pais_clicked));
	this->vBoxPais.pack_start(bAgregarPais);
	this->vBoxPais.pack_start(bEliminarPais);
	
	bSalir.set_label("Salir");
	bSalir.signal_clicked().connect( sigc::mem_fun(*this,
            &VentanaMapas::on_ventana_close) );
	bMisiones.set_label("Agregar Misión");
	bMisiones.signal_clicked().connect( sigc::mem_fun(*this,
	            &VentanaMapas::on_misiones_clicked) );
	this->vBoxSalir.pack_start(bSalir);
	this->vBoxSalir.pack_start(bMisiones);

	hBox.pack_start(vBoxContinente, true, true, 0);
	hBox.pack_start(vBoxPais,true, true,0);
	hBox.pack_start(vBoxConeccion,true,true,0);
	hBox.pack_start(vBoxSalir,true,true,0);
	hBox.set_homogeneous(false);
	
	vBox.pack_start(hBox, false, true,0);

	//vertical.set_homogeneous(false);
	add(vBox);
	set_title("Editor de Mapas");
	set_border_width(4);
	set_position(Gtk::WIN_POS_CENTER);
	set_size_request(1024,768);
	set_resizable(false);
	show_all();
}

VentanaMapas :: ~VentanaMapas(){

}

//metodos del menu de arriba

void VentanaMapas :: on_nuevo_clicked(){
	
	string filename;
	bool ok = msgNuevoMapa(filename);
	if(ok){
		vContinentes.vaciar();
		cargarImagen = true;
		area.loadFile(filename);
		area.redraw();
	}
}

void VentanaMapas :: on_cargar_clicked(){
	
}

void VentanaMapas :: on_guardar_clicked(){
	string ruta("./imagen");
	area.guardarImagen(ruta);
}

void VentanaMapas :: on_continente_clicked(){
	
	bAgregarConeccion.set_active(false);
	bAgregarPais.set_active(false);
	bEliminarConeccion.set_active(false);
	bEliminarPais.set_active(false);
	
	if(cargarImagen == false){
			
		escribirConsola(MNCCONTINENTE);
		return;
	}
	iniOk = false;
	iniEliOk = false;
	
	escribirConsola("");
	agregarContinente();
}

void VentanaMapas :: on_eliminar_continente_clicked(){
	
	bAgregarConeccion.set_active(false);
	bAgregarPais.set_active(false);
	bEliminarConeccion.set_active(false);
	bEliminarPais.set_active(false);
	
	if(cargarImagen == false){
				
		escribirConsola(MNCECONTINENTE);
		return;
	}
	iniOk = false;
	iniEliOk = false;
	
	escribirConsola("");
	eliminarContinente();
}

void VentanaMapas :: on_pais_clicked(){
	
	bAgregarConeccion.set_active(false);
	bEliminarConeccion.set_active(false);
	bEliminarPais.set_active(false);
	
	if(bAgregarPais.get_state() == Gtk::STATE_ACTIVE){
		bAgregarPais.set_active(false);
		return;
	}
	
	if(cargarImagen == false){
		
		escribirConsola(MNCPAIS);
		bAgregarPais.set_active(false);
		return;
	}
	
	iniOk = false;
	iniEliOk = false;

	escribirConsola(HTPAIS);
	return;
}

void VentanaMapas :: on_eliminar_pais_clicked(){
	
	bAgregarConeccion.set_active(false);
	bEliminarConeccion.set_active(false);
	bAgregarPais.set_active(false);
			
	if(bEliminarPais.get_state() == Gtk::STATE_ACTIVE){
		bEliminarPais.set_active(false);
		return;
	}
	
	if(cargarImagen == false){
			
		escribirConsola(MNCEPAIS);
		bEliminarPais.set_active(false);
		return;
	}
		
	iniOk = false;
	iniEliOk = false;
	
	escribirConsola(HTEPAIS);
	return;
}

void VentanaMapas :: on_coneccion_clicked(){
	
	bAgregarPais.set_active(false);
	bEliminarConeccion.set_active(false);
	bEliminarPais.set_active(false);
		
	if(bAgregarConeccion.get_state() == Gtk::STATE_ACTIVE){
		bAgregarConeccion.set_active(false);
		return;
	}
	
	if(cargarImagen == false){
				
		escribirConsola(MNCCONECCION);
		bAgregarConeccion.set_active(false);
		return;
	}
	
	iniEliOk = false;
	
	escribirConsola(HTCONECCION);
	return;
}

void VentanaMapas :: on_eliminar_coneccion_clicked(){
	
	bAgregarPais.set_active(false);
	bAgregarConeccion.set_active(false);
	bEliminarPais.set_active(false);
			
	if(bEliminarConeccion.get_state() == Gtk::STATE_ACTIVE){
		bEliminarConeccion.set_active(false);
		return;
	}
	
	if(cargarImagen == false){
					
		escribirConsola(MNCECONECCION);
		bEliminarConeccion.set_active(false);
		return;
	}
	
	iniOk = false;

	escribirConsola(HTECONECCION);
	return;
	
}

void VentanaMapas :: on_misiones_clicked(){
	
	iniOk = false;
	iniEliOk = false;
	
	escribirConsola(HTMISIONES);
	return;
}

bool VentanaMapas :: on_imagen_clicked(GdkEventButton* event){
	
	int x = (int)event->x;
	int y = (int)event->y;
	
	string nombreP, nombreC;
	
	if(this->checkClickPais(x, y, nombreP, nombreC)){
		escribirDatos(nombreP, nombreC);
	}
	
	if(bAgregarPais.get_state() == Gtk::STATE_ACTIVE){
		agregarPais(x, y);
		bAgregarPais.set_active(false);
	}
	else if(bAgregarConeccion.get_state() == Gtk::STATE_ACTIVE){
		agregarConeccion(x,y);
		if(iniOk == false)
			bAgregarConeccion.set_active(false);
	}
	else if(bEliminarPais.get_state() == Gtk::STATE_ACTIVE){
		eliminarPais(x,y);
		bEliminarPais.set_active(false);
	}
	else if(bEliminarConeccion.get_state() == Gtk::STATE_ACTIVE){
		eliminarConeccion(x,y);
		if(iniEliOk == false)
			bEliminarConeccion.set_active(false);
	}
	return true;
}

void VentanaMapas :: on_ventana_close(){
	int response = msgAdvertenciaSalir();
	if(response == Gtk::RESPONSE_YES){
		Gtk::Main::quit();
	}
}

void VentanaMapas :: on_salir_clicked(){
	on_ventana_close();
}

void VentanaMapas :: agregarContinente(){
	
	int response;
	string nombre;
	
	VAgregarContinente vac;
	response = vac.run();
	switch(response){
		case Gtk::RESPONSE_ACCEPT:{
			nombre = vac.getText();
			if(nombre.size() != 0){
				this->vContinentes.add(nombre);
			}
		  	break;
		}
		default:{
			break;
		}
	}
}

void VentanaMapas :: agregarPais(int x, int y){
	
	string nPais, nContinente, nombre;
	if(this->vContinentes.get_Size() == 0){
		msgErrorNoHayContinentes();
		return;
	}
	if(checkClickPais(x, y, nPais, nContinente)){
		msgErrorMismoClick(nPais);
		return;
	}
	else{
		int response;
		VAgregarPais vap(this->vContinentes);
		response = vap.run();
		switch(response){
			case Gtk::RESPONSE_ACCEPT:{
				nombre = vap.get_Nombre();
				bool error = checkNombrePais(nombre);
				if(error || nombre.size() == 0){
					msgErrorMismoNombre();
				}
				else{
					cargaPais(nombre, vap.get_Radio(), x, y, vap.get_Continente());
					area.redraw();
					//area.dibujarCirculo(x,y, vap.get_Radio(), nombre);
				}
				
			  	break;
			}
			default:{
				break;
			}
		}
	}	
}

void VentanaMapas :: cargaPais(string nombre, int radio, int x, int y, string continente){
	
	Continente *c = this->vContinentes.get_Continente(continente);
	c->agregarPais(nombre, radio, x, y, *c, vContinentes);
}

void VentanaMapas :: eliminarContinente(){
	
	if(vContinentes.get_Size() != 0){
		VEliminarContinente vecont(vContinentes);
		int respuesta = vecont.run();
		switch(respuesta){
			case Gtk::RESPONSE_ACCEPT:{
				string nombre = vecont.get_Continente();
				vContinentes.eliminarContinente(nombre);
				area.redraw();
				break;
			}
			default:{
				break;
			}
		}
		return;
	}
	else{
		escribirConsola("No hay continentes para eliminar.");
		return;
	}
}

void VentanaMapas :: eliminarPais(int x, int y){
	
	string pais, continente;
	
	if(checkClickPais(x, y, pais, continente)){
		Continente *c = vContinentes.get_Continente(continente);
		c->eliminarPais(pais);
		area.redraw();
		return;
	}
	return;
}

bool VentanaMapas :: checkClickPais(int x, int y, string &nombP, string &nombC){
	
	int xo, yo, total;
	int tamanio = this->vContinentes.get_Size();
	
	for(int i = 0; i < tamanio; i++){
		Continente *c = vContinentes.get_Continente(i);
		for(int j = 0; j < c->get_CantPaises(); j++){
			Pais *p = c->get_Pais(j);
			p->get_Pos(xo,yo);
			int radio = p->get_Radio();
			total = (x-xo)*(x-xo)+(y-yo)*(y-yo);
			if(total <= (radio*radio)){
				nombP = p->get_Nombre();
				nombC = c->get_Nombre();
				return true;
			}
		}
	}
	
	return false;
}

bool VentanaMapas :: checkNombrePais(string nombP){
	
	string nombre;
	
	for(int i = 0; i < this->vContinentes.get_Size(); i++){
		Continente *c = vContinentes.get_Continente(i);
		for(int j = 0; j < c->get_CantPaises(); j++){
			Pais *p = c->get_Pais(j);
			nombre = p->get_Nombre();
			if(nombre.compare(nombP) == 0){
				return true;
			}
		}
	}
	return false;
}

void VentanaMapas :: agregarConeccion(int x, int y){
	
	string nombreP, nombreC;
	
	if(iniOk == false){
		if(checkClickPais(x, y, nombreP, nombreC)){
			Continente *c = this->vContinentes.get_Continente(nombreC);
			Pais *p = c->get_Pais(nombreP);
			nP1 = p->get_Nombre();
			nC1 = p->get_Continente()->get_Nombre();
			iniOk = true;
		}
	}
	else{
		if(checkClickPais(x, y, nombreP, nombreC)){
			if(nombreP.compare(nP1) != 0){
				Continente *c = this->vContinentes.get_Continente(nombreC);
				Pais *p = c->get_Pais(nombreP);
				//ingreso los datos en el segundo pais
				nP2 = p->get_Nombre();
				nC2 = p->get_Continente()->get_Nombre();
				p->agregar_Coneccion(nP1, nC1);
				//ingreso los datos en el primer pais
				Continente *c2 = this->vContinentes.get_Continente(nC1);
				Pais *p2 = c2->get_Pais(nP1);
				p2->agregar_Coneccion(nP2, nC2);
				area.redraw();
			}
				
		}
		iniOk = false;
	}
	
}

void VentanaMapas :: eliminarConeccion(int x, int y){
	
	string nombreP, nombreC;
	
	if(iniEliOk == false){
		if(checkClickPais(x, y, nombreP, nombreC)){
			Continente *c = this->vContinentes.get_Continente(nombreC);
			Pais *p = c->get_Pais(nombreP);
			nP1 = p->get_Nombre();
			nC1 = p->get_Continente()->get_Nombre();
			iniEliOk = true;
		}
	}
	else{
		if(checkClickPais(x, y, nombreP, nombreC)){
			if(nombreP.compare(nP1) != 0){
				Continente *c = this->vContinentes.get_Continente(nombreC);
				Pais *p = c->get_Pais(nombreP);
				//ingreso los datos en el segundo pais
				nP2 = p->get_Nombre();
				nC2 = p->get_Continente()->get_Nombre();
				p->borrar_Coneccion_Compuesto(nP1);
				area.redraw();
			}
				
		}
		iniEliOk = false;
	}
	
}

void VentanaMapas :: escribirConsola(string texto){
	
	detallesBuffer = Gtk::TextBuffer::create();
	detallesBuffer->set_text(texto);
								
	detalles.set_buffer(detallesBuffer);
}

void VentanaMapas :: escribirDatos(string nombreP, string nombreC){
	
	Continente *c = this->vContinentes.get_Continente(nombreC);
	Pais *p = c->get_Pais(nombreP);
	
	int x,y, numero;
	p->get_Pos(x,y);
	numero = c->get_CantPaises() - 1;
	string radio, sx, sy, num;
	char cadena[10];
	sprintf(cadena,"%d",p->get_Radio());
	radio.assign(cadena);
	sprintf(cadena,"%d", x);
	sx.assign(cadena);
	sprintf(cadena,"%d", y);
	sy.assign(cadena);
	sprintf(cadena,"%d", numero);
	num.assign(cadena);
	
	
	string s1("Nombre: ");
	s1.append(nombreP);
	
	s1.append("\nEl país ");
	s1.append(nombreP);
	s1.append(" se encuentra en el continente ");
	s1.append(nombreC);
	s1.append(", comparte este último con ");
	s1.append(num);
	s1.append(" paises más, tiene un radio de: ");
	s1.append(radio);
	s1.append(" y su posición en el mapa es (");
	s1.append(sx);
	s1.append(",");
	s1.append(sy);
	s1.append(").\n Sus paises limitrofes son: ");
	for(int i = 0; i < p->cantidad_Conecciones(); i++){
		string nP, nC;
		p->get_Coneccion(i, nP, nC);
		s1.append(nP);
		s1.append(", ");
	}
	
	escribirConsola(s1);

}

bool VentanaMapas :: msgNuevoMapa(string &filename){
	
	Gtk::FileChooserDialog dialog("Por favor elija una imagen",
	        Gtk::FILE_CHOOSER_ACTION_OPEN);
	dialog.set_transient_for(*this);
	
	dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
	dialog.add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK);
	
	Gtk::FileFilter filter_image;
	filter_image.set_name("Imagenes");
	filter_image.add_mime_type("image/jpeg");
	filter_image.add_mime_type("image/png");
	dialog.add_filter(filter_image);
	
	int response = dialog.run();
	
	switch(response)
	{
	  case(Gtk::RESPONSE_OK):
	  {
	    filename = dialog.get_filename();
	    if(filename.size() != 0){
	    	return true;
	    }
	  }
	  default: ;
	  	       break;
	}
	return false;
}


int VentanaMapas :: msgAdvertenciaSalir(){
	string msg("Asegurese de haber guardado el mapa antes de salir. Si sale sin haber guardado perdera los datos de su nuevo mapa. ");
	Gtk::MessageDialog dialogoError(*this, "¿Está seguro que desea salir?",
	        false /* use_markup */, Gtk::MESSAGE_WARNING,
	        Gtk::BUTTONS_YES_NO);
	
	dialogoError.set_title("Salir");

	dialogoError.set_secondary_text(msg);
	
	int response = dialogoError.run();
	return response;
}

void VentanaMapas :: msgErrorNoHayContinentes(){

	string msg("No puede agregar un país hasta que no haya declarado un continente ");
	Gtk::MessageDialog dialogoError("No se ha agregado ningun continente",false,Gtk::MESSAGE_INFO,
											Gtk::BUTTONS_OK,false);
	dialogoError.set_secondary_text(msg);
	dialogoError.run();
}

void VentanaMapas :: msgErrorMismoClick(string nombre){
	string msg("La posicion donde quiere insertar el nuevo pais es el territorio de ");
	msg.append(nombre);
	
	Gtk::MessageDialog dialogoError("Posicion invalida",false,Gtk::MESSAGE_INFO,
											Gtk::BUTTONS_OK,false);
	dialogoError.set_secondary_text(msg);
	dialogoError.run();
}

void VentanaMapas :: msgErrorMismoNombre(){
	string msg("El nombre del país seleccionado es inválido,"
			" ya correspone a otro territorio o no se ingresó ningún nombre.");
	
	Gtk::MessageDialog dialogoError("Nombre invalido",false,Gtk::MESSAGE_INFO,
											Gtk::BUTTONS_OK,false);
	dialogoError.set_secondary_text(msg);
	dialogoError.run();
}
